package com.gitee.qdbp.general.common.factory;

import java.util.Map;
import java.util.Map.Entry;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import com.gitee.qdbp.general.common.api.sms.service.ISmsService;
import com.gitee.qdbp.general.common.biz.sms.service.BaseSmsService;
import com.gitee.qdbp.general.common.biz.sms.service.NullSmsService;
import com.gitee.qdbp.general.common.biz.sms.utils.ISmsBaseBusiness;
import com.gitee.qdbp.tools.cache.ICacheService;

/**
 * 短信服务实例工厂类
 *
 * @author zhaohuihua
 * @version 180722
 */
public class SmsServiceFactoryBean implements FactoryBean<ISmsService>, InitializingBean, ApplicationContextAware {

    private boolean singleton = true;
    private boolean initialized = false;
    private ISmsService singletonInstance;

    private Class<? extends ISmsService> instanceType;
    protected ICacheService cache;
    protected ISmsBaseBusiness utils;

    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    private ISmsService createInstance() throws Exception {
        ISmsService smsService;
        if (instanceType == null) {
            smsService = new NullSmsService();
        } else {
            smsService = instanceType.newInstance();
        }
        if (smsService instanceof BaseSmsService) {
            BaseSmsService baseSmsService = (BaseSmsService) smsService;
            if (utils != null) {
                baseSmsService.setCacheService(cache);
            }
            if (cache != null) {
                baseSmsService.setBaseBusiness(utils);
            } else {
                Map<String, ICacheService> caches = applicationContext.getBeansOfType(ICacheService.class);
                if (caches != null && !caches.isEmpty()) {
                    for (Entry<String, ICacheService> entry : caches.entrySet()) {
                        baseSmsService.setCacheService(entry.getValue());
                        break;
                    }
                }
            }
            baseSmsService.init();
        }

        return smsService;
    }

    @Override
    public ISmsService getObject() throws Exception {
        if (isSingleton()) {
            if (!this.initialized) {
                this.singletonInstance = createInstance();
                this.initialized = true;
            }
            return this.singletonInstance;
        } else {
            return createInstance();
        }
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        if (isSingleton()) {
            this.initialized = true;
            this.singletonInstance = createInstance();
        }
    }

    @Override
    public Class<?> getObjectType() {
        return ISmsService.class;
    }

    public void setSingleton(boolean singleton) {
        this.singleton = singleton;
    }

    @Override
    public boolean isSingleton() {
        return singleton;
    }

    public Class<? extends ISmsService> getInstanceType() {
        return instanceType;
    }

    public void setInstanceType(Class<? extends ISmsService> instanceType) {
        this.instanceType = instanceType;
    }

    public void setBaseBusiness(ISmsBaseBusiness utils) {
        this.utils = utils;
    }

    public void setCacheService(ICacheService cache) {
        this.cache = cache;
    }

}
